using System;
using System.Collections;
using System.Web;

using WoWAddonRefresh.Entities;
using System.Collections.Generic;

using System.Data.Linq;
using System.Linq;
using System.Linq.Expressions;
using System.IO;

namespace WoWAddonRefresh {
    public class Parser {
        private static IFormatProvider FORMAT = new System.Globalization.CultureInfo("en-US", true);

        public static List<Addon> ParseHTML(string html) {
            List<Addon> result = new List<Addon>();
            ArrayList rows = new ArrayList();
            string tempString = html;
            string rowBegining = "<tr";
            string rowEnd = "</tr>";
            int rowEnd_Length = rowEnd.Length;
            // int row_num = 0;
            while (tempString.IndexOf(rowEnd) > 0) {
                int start = tempString.IndexOf(rowBegining);
                if (start < 0) break;
                int length = tempString.IndexOf(rowEnd, start) + rowEnd_Length - start;
                if (length > 0) {
                    string row = tempString.Substring(start, length);
                    rows.Add(row);
                    if (row.Length > 0) {
                        Addon addon = ParseRow(row);
                        if (addon != null) {
                            result.Add(addon);
                        }
                        tempString = tempString.Replace(row, "");
                        // row_num++;
                    }
                }
                else {
                    Console.WriteLine(tempString);
                    return result;
                }
            }
            return result;
        }

        private static Addon ParseRow(string row) {
            Addon addon = new Addon();
            string begining = "<td";
            string end = "</td>";
            int end_length = end.Length;
            string tempString = row;
            int td_ix = 0;
            while (tempString.IndexOf(end) > 0) {
                int start = tempString.IndexOf(begining);
                int length = tempString.IndexOf(end) + end_length - start;
                string td = tempString.Substring(start, length);
                switch (td_ix) {
                    case 0:
                        addon.DownloadURL = Parser.GetHref(td);
                        break;
                    case 1:
                        addon.Name = HttpUtility.HtmlDecode(Parser.ReplaceHTML(td)).Trim();
                        if (addon.Name == string.Empty) return null;
                        addon.NameLink = Parser.GetHref(td, null);
                        break;
                    case 2:
                        break;
                    case 3:
                        break;
                    case 4:
                        DateTime uploadDate = DateTime.MinValue;
                        if (DateTime.TryParse(Parser.ReplaceHTML(td), FORMAT, System.Globalization.DateTimeStyles.NoCurrentDateDefault, out uploadDate)) {
                            addon.UploadDate = uploadDate;
                        }

                        if (addon.UploadDate.Value.Year < 2006) {
                            addon.UploadDate = DateTime.MinValue;
                        }
                        break;

                    default:
                        break;
                }
                tempString = tempString.Replace(td, "");
                td_ix++;
            }

            addon.LocalDate = GetAddonLocalDate(addon);

            return addon;
        }

        public static DateTime? GetAddonLocalDate(Addon addon) {
            try {
                Addon savedAddon = StaticContext.DBContext.Addon.Where(a => a.DownloadURL == addon.DownloadURL).FirstOrDefault();
                if (savedAddon != null && savedAddon.Toc != null && savedAddon.Path != null) {
                    string fn = Constants.WoWFolder + "Interface\\Addons\\" + savedAddon.Path + "\\" + savedAddon.Toc;
                    FileInfo fi = new FileInfo(fn);
                    if (fi.Exists) {
                        DateTime result = fi.LastWriteTime > fi.LastAccessTime ? fi.LastWriteTime : fi.LastAccessTime;
                        if (result < fi.CreationTime) result = fi.CreationTime;
                        savedAddon.LocalDate = result;
                        StaticContext.DBContext.SubmitChanges();
                        return result;
                    }
                    return null;
                }
                return null;
            }
            catch {
                return null;
            }
        }

        public static string GetHref(string td) {
            int start = td.IndexOf("href=\"");
            if (start > 0) {
                start = start + 6;
                int length = td.IndexOf("\"", start) - start;
                if (length > 0) {
                    string result = td.Substring(start, length);
                    return result;
                }
                else return null;
            }
            else return null;
        }

        public static string GetHref(string td, string search) {
            string result = GetHref(td);

            if (search != null && search.Trim().Length > 0) {
                if (result != null && result.IndexOf(search) == -1) {
                    int start = td.IndexOf("href=\"");
                    string cut = td.Substring(start + 5);
                    result = GetHref(cut, search);
                }
            }

            return result;
        }

        public static string GetURL(string input) {
            int start = input.IndexOf("URL=") + 4;
            string result = input.Substring(start, (input.IndexOf("\"", start) - (start)));
            return result;
        }

        public static string ReplaceHTML(string html) {
            string tempString = html;
            string htmlBegining = "<";
            string htmlScript = "<script";
            string htmlEnd = ">";
            if (tempString.IndexOf(htmlScript) > -1) return string.Empty;
            int htmlEndLength = htmlEnd.Length;
            while (tempString.IndexOf(htmlEnd) > 0) {
                int start = tempString.IndexOf(htmlBegining);
                if (start == -1) break;
                int finish = tempString.IndexOf(htmlEnd, start);
                if (finish == -1) break;
                int length = finish + htmlEndLength - start;
                string result = tempString.Substring(start, length);
                tempString = tempString.Replace(result, "");
            }
            return tempString;
        }

    }
}
